package com.example.chamberlainserver.Service.impl;

import com.example.chamberlainserver.Entry.StorageLocation;
import com.example.chamberlainserver.Service.StorageLocationService;
import com.example.chamberlainserver.mapper.MaterialMapper;
import com.example.chamberlainserver.mapper.StorageLocationMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 存放位置服务实现类
 */
@Service
public class StorageLocationServiceImpl implements StorageLocationService {

    @Autowired
    private StorageLocationMapper storageLocationMapper;
    
    @Autowired
    private MaterialMapper materialMapper;

    @Override
    @Transactional
    public StorageLocation addLocation(StorageLocation location) {
        // 验证位置信息
        validateLocation(location);
        
        // 检查位置名称是否已存在
        StorageLocation existingLocation = storageLocationMapper.getLocationByName(location.getLocationName());
        if (existingLocation != null) {
            throw new IllegalArgumentException("位置名称已存在");
        }
        
        // 如果有父位置，检查父位置是否存在
        if (location.getParentId() != null && location.getParentId() > 0) {
            StorageLocation parentLocation = storageLocationMapper.getLocationById(location.getParentId());
            if (parentLocation == null) {
                throw new IllegalArgumentException("父位置不存在");
            }
            
            // 如果未设置位置路径，则自动生成
            if (location.getLocationPath() == null || location.getLocationPath().trim().isEmpty()) {
                String parentPath = parentLocation.getLocationPath();
                location.setLocationPath(parentPath + "/" + location.getLocationName());
            }
        } else {
            // 顶级位置，如果未设置位置路径，则使用位置名称作为路径
            if (location.getLocationPath() == null || location.getLocationPath().trim().isEmpty()) {
                location.setLocationPath(location.getLocationName());
            }
        }
        
        // 插入位置记录
        storageLocationMapper.insertLocation(location);
        
        // 返回插入后的位置信息（包含自增ID）
        return location;
    }

    @Override
    @Transactional
    public StorageLocation updateLocation(StorageLocation location) {
        // 检查位置是否存在
        StorageLocation existingLocation = storageLocationMapper.getLocationById(location.getId());
        if (existingLocation == null) {
            throw new IllegalArgumentException("位置不存在");
        }
        
        // 验证位置信息
        validateLocation(location);
        
        // 检查位置名称是否与其他位置重复
        StorageLocation locationWithSameName = storageLocationMapper.getLocationByName(location.getLocationName());
        if (locationWithSameName != null && !locationWithSameName.getId().equals(location.getId())) {
            throw new IllegalArgumentException("位置名称已存在");
        }
        
        // 检查是否修改了父位置
        boolean parentChanged = (location.getParentId() == null && existingLocation.getParentId() != null) ||
                               (location.getParentId() != null && !location.getParentId().equals(existingLocation.getParentId()));
        
        // 如果修改了父位置，检查新父位置是否存在，并更新位置路径
        if (parentChanged) {
            // 检查是否形成循环引用
            if (location.getParentId() != null && location.getParentId().equals(location.getId())) {
                throw new IllegalArgumentException("不能将自己设为父位置");
            }
            
            // 检查新父位置是否是当前位置的子位置（防止循环引用）
            if (location.getParentId() != null && isChildLocation(location.getId(), location.getParentId())) {
                throw new IllegalArgumentException("不能将子位置设为父位置");
            }
            
            // 如果有新父位置，检查父位置是否存在
            if (location.getParentId() != null && location.getParentId() > 0) {
                StorageLocation parentLocation = storageLocationMapper.getLocationById(location.getParentId());
                if (parentLocation == null) {
                    throw new IllegalArgumentException("父位置不存在");
                }
                
                // 更新位置路径
                String parentPath = parentLocation.getLocationPath();
                location.setLocationPath(parentPath + "/" + location.getLocationName());
            } else {
                // 更新为顶级位置
                location.setLocationPath(location.getLocationName());
            }
            
            // 更新子位置的路径
            updateSubLocationPaths(location.getId(), existingLocation.getLocationPath(), location.getLocationPath());
        } else if (!location.getLocationName().equals(existingLocation.getLocationName())) {
            // 如果只修改了位置名称，也需要更新位置路径
            String oldPath = existingLocation.getLocationPath();
            String newPath;
            
            if (existingLocation.getParentId() != null && existingLocation.getParentId() > 0) {
                // 有父位置，更新路径中的最后一段
                int lastSlashIndex = oldPath.lastIndexOf('/');
                if (lastSlashIndex >= 0) {
                    newPath = oldPath.substring(0, lastSlashIndex + 1) + location.getLocationName();
                } else {
                    newPath = location.getLocationName();
                }
            } else {
                // 顶级位置
                newPath = location.getLocationName();
            }
            
            location.setLocationPath(newPath);
            
            // 更新子位置的路径
            updateSubLocationPaths(location.getId(), oldPath, newPath);
        } else {
            // 保持原有路径
            location.setLocationPath(existingLocation.getLocationPath());
        }
        
        // 更新位置记录
        storageLocationMapper.updateLocation(location);
        
        // 返回更新后的位置信息
        return location;
    }

    @Override
    @Transactional
    public boolean deleteLocation(Integer id) {
        // 检查位置是否存在
        StorageLocation existingLocation = storageLocationMapper.getLocationById(id);
        if (existingLocation == null) {
            return false;
        }
        
        // 检查是否有子位置
        int subLocationCount = storageLocationMapper.countSubLocations(id);
        if (subLocationCount > 0) {
            throw new IllegalArgumentException("该位置下有子位置，无法删除");
        }
        
        // 检查是否有物资使用该位置
        int materialCount = materialMapper.countMaterialsByLocation(id);
        if (materialCount > 0) {
            throw new IllegalArgumentException("该位置下有物资，无法删除");
        }
        
        // 删除位置记录
        int rows = storageLocationMapper.deleteLocation(id);
        
        return rows > 0;
    }

    @Override
    public StorageLocation getLocationById(Integer id) {
        return storageLocationMapper.getLocationById(id);
    }

    @Override
    public List<StorageLocation> getAllLocations() {
        return storageLocationMapper.getAllLocations();
    }

    @Override
    public List<StorageLocation> getLocationTree() {
        // 获取所有位置
        List<StorageLocation> allLocations = storageLocationMapper.getAllLocations();
        
        // 获取顶级位置
        List<StorageLocation> topLocations = allLocations.stream()
                .filter(location -> location.getParentId() == null || location.getParentId() == 0)
                .collect(Collectors.toList());
        
        // 构建位置树
        return buildLocationTree(topLocations, allLocations);
    }

    @Override
    public List<StorageLocation> getSubLocations(Integer parentId) {
        return storageLocationMapper.getSubLocations(parentId);
    }

    @Override
    public List<StorageLocation> getTopLocations() {
        return storageLocationMapper.getTopLocations();
    }

    @Override
    public List<StorageLocation> searchLocationsByName(String name) {
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("搜索关键字不能为空");
        }
        return storageLocationMapper.searchLocationsByName(name.trim());
    }

    @Override
    public List<StorageLocation> getLocationsByManager(String manager) {
        if (manager == null || manager.trim().isEmpty()) {
            throw new IllegalArgumentException("管理员名称不能为空");
        }
        return storageLocationMapper.getLocationsByManager(manager.trim());
    }

    @Override
    @Transactional
    public StorageLocation updateLocationPath(Integer id, String locationPath) {
        // 检查位置是否存在
        StorageLocation existingLocation = storageLocationMapper.getLocationById(id);
        if (existingLocation == null) {
            throw new IllegalArgumentException("位置不存在");
        }
        
        // 验证位置路径
        if (locationPath == null || locationPath.trim().isEmpty()) {
            throw new IllegalArgumentException("位置路径不能为空");
        }
        
        // 检查路径是否已存在
        int pathCount = storageLocationMapper.checkLocationPathExists(locationPath);
        if (pathCount > 0) {
            throw new IllegalArgumentException("位置路径已存在");
        }
        
        // 更新位置路径
        String now = LocalDateTime.now().toString();
        storageLocationMapper.updateLocationPath(id, locationPath, now);
        
        // 更新子位置的路径
        updateSubLocationPaths(id, existingLocation.getLocationPath(), locationPath);
        
        // 获取更新后的位置信息
        return storageLocationMapper.getLocationById(id);
    }
    
    /**
     * 验证位置信息
     * @param location 位置信息
     */
    private void validateLocation(StorageLocation location) {
        // 验证位置名称
        if (location.getLocationName() == null || location.getLocationName().trim().isEmpty()) {
            throw new IllegalArgumentException("位置名称不能为空");
        }
    }
    
    /**
     * 检查是否是子位置
     * @param parentId 父位置ID
     * @param childId 子位置ID
     * @return 是否是子位置
     */
    private boolean isChildLocation(Integer parentId, Integer childId) {
        List<StorageLocation> subLocations = storageLocationMapper.getSubLocations(parentId);
        for (StorageLocation subLocation : subLocations) {
            if (subLocation.getId().equals(childId)) {
                return true;
            }
            if (isChildLocation(subLocation.getId(), childId)) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 更新子位置的路径
     * @param parentId 父位置ID
     * @param oldParentPath 旧的父位置路径
     * @param newParentPath 新的父位置路径
     */
    private void updateSubLocationPaths(Integer parentId, String oldParentPath, String newParentPath) {
        List<StorageLocation> subLocations = storageLocationMapper.getSubLocations(parentId);
        for (StorageLocation subLocation : subLocations) {
            String oldPath = subLocation.getLocationPath();
            String newPath = oldPath.replace(oldParentPath, newParentPath);
            
            // 更新子位置路径
            String now = LocalDateTime.now().toString();
            storageLocationMapper.updateLocationPath(subLocation.getId(), newPath, now);
            
            // 递归更新子位置的子位置
            updateSubLocationPaths(subLocation.getId(), oldPath, newPath);
        }
    }
    
    /**
     * 构建位置树
     * @param parentLocations 父位置列表
     * @param allLocations 所有位置列表
     * @return 位置树
     */
    private List<StorageLocation> buildLocationTree(List<StorageLocation> parentLocations, List<StorageLocation> allLocations) {
        List<StorageLocation> result = new ArrayList<>();
        
        for (StorageLocation parent : parentLocations) {
            // 深拷贝父位置，避免修改原始数据
            StorageLocation parentCopy = new StorageLocation();
            parentCopy.setId(parent.getId());
            parentCopy.setLocationName(parent.getLocationName());
            parentCopy.setParentId(parent.getParentId());
            parentCopy.setLocationPath(parent.getLocationPath());
            parentCopy.setDescription(parent.getDescription());
            parentCopy.setManager(parent.getManager());
            parentCopy.setCreateTime(parent.getCreateTime());
            parentCopy.setUpdateTime(parent.getUpdateTime());
            
            // 查找子位置
            List<StorageLocation> children = allLocations.stream()
                    .filter(location -> parent.getId().equals(location.getParentId()))
                    .collect(Collectors.toList());
            
            // 递归构建子位置树
            if (!children.isEmpty()) {
                List<StorageLocation> childrenTree = buildLocationTree(children, allLocations);
                // 设置子位置到父位置的children字段
                parentCopy.setChildren(childrenTree);
            }
            
            result.add(parentCopy);
        }
        
        return result;
    }
}